package com.qg.service;


import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.fastjson.JSONObject;

import com.qg.dto.Dto;

import com.qg.exception.GoodsException;
import com.qg.module.pojo.QgGoods;
import com.qg.module.pojo.QgGoodsTempStock;
import com.qg.module.pojo.QgOrder;
import com.qg.module.pojo.QgUser;
import com.qg.module.vo.GetQGMassage;
import com.qg.module.vo.GoodsVo;

import com.qg.utils.*;

import org.apache.activemq.command.ActiveMQTextMessage;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.annotation.JmsListener;
import org.springframework.jms.annotation.JmsListeners;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Component
public class LocalGoodsServiceImpl implements LocalGoodsService {

    @Reference
    private QgOrderService qgOrderService;
    @Reference
    private QgGoodsService qgGoodsService;

    @Reference
    private QgGoodsTempStockService qgGoodsTempStockService;

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private ActieMQaUtil actieMQaUtil;

    @Override
    public Dto queryGoodsById(String id) throws Exception {
        GoodsVo goodsVo = null;
        //=====redis中没有，则走数据库查询，并将结果写入到redis
        //redis获取商品信息
        String goodsVoJson = redisUtil.getStr(Constants.goodsPrefix + id);

        //redis商品信息是空
        if (EmptyUtils.isEmpty(goodsVoJson)) {
            goodsVo = new GoodsVo();
            //====获取商品信息并装换vo
            QgGoods qgGoods = qgGoodsService.getQgGoodsById(id);
            BeanUtils.copyProperties(qgGoods, goodsVo);
            //======获取临时库存数量
            //======1.获取临时库存表中，goods_id 为id的有效的记录数->用户已消费或待消费记录数 100 activeCount
            Map<String, Object> param = new HashMap<String, Object>();
            param.put("goodsId", id);
            param.put("active", 1);
            Integer activeCount = qgGoodsTempStockService.getQgGoodsTempStockCountByMap(param);
            //=======获取实际库存存入vo
            Integer currentCount = goodsVo.getStock() - activeCount;
            goodsVo.setCurrentStock(currentCount);
            //放在redis当中
            redisUtil.setStr(Constants.goodsPrefix + id, JSONObject.toJSONString(goodsVo));
        } else {
            //要么把redis查到的商品信息转为vo
            goodsVo = JSONObject.parseObject(goodsVoJson, GoodsVo.class);
        }
        return DtoUtil.returnDataSuccess(goodsVo);
    }


    /**
     * 接受并监听消息
     *
     * @param getQGMassage
     * @return
     * @throws Exception
     */
    @JmsListener(destination = Constants.ActiveMQMassage.Distnection)
    private void getGoods(GetQGMassage getQGMassage) throws Exception {
        String userID = getQGMassage.getUserID();
        String goodsID = getQGMassage.getGoodsID();
        //======1.根据token知道是那个用户 获取用户信息
        // String userJson=redisUtil.getStr(token);


        //加锁
        while (!redisUtil.lock(Constants.Lock.lockPrefix + goodsID, Constants.Lock.outTime)) {
            Thread.sleep(3);
        }
        //转换为用户信息
        //QgUser qgUser= JSONObject.parseObject(userJson,QgUser.class);

        //=====2.查看用户是否已经抢购过该商品，如果用户有抢购成功未支付的或已经支付成功的记录，则不能抢
        String QGUserValue = redisUtil.getStr(Constants.QGUser.QGUserPrefix + goodsID + ":" + userID);
        if ("2".equals(QGUserValue) || "1".equals(QGUserValue)) {
            //删除锁
            redisUtil.del(Constants.Lock.lockPrefix + goodsID);
            //缓存抢购过用户标识
            redisUtil.setStr(Constants.QGUser.QGUserPrefix + goodsID + ":" + userID, Constants.QGUser.QGUser);
            return;
            //return DtoUtil.returnFail(GoodsException.USER_REPEAT_GET.getCode().toString(),GoodsException.USER_REPEAT_GET.getMessage());
        }

        //=====3.判断库存是否大于0,如果大于0则进入抢购环节
        //=====获取商品信息并且判断仓库是否空
        String goodsVoJson = redisUtil.getStr(Constants.goodsPrefix + goodsID);
        GoodsVo goodsVo = JSONObject.parseObject(goodsVoJson, GoodsVo.class);
        if (goodsVo.getCurrentStock() <= 0) {
            //删除锁
            redisUtil.del(Constants.Lock.lockPrefix + goodsID);
            redisUtil.setStr(Constants.QGUser.QGUserPrefix + goodsID + ":" + userID, Constants.QGUser.QGUserStockNull);
            return;
            //return DtoUtil.returnFail(GoodsException.GOODS_IS_CLEAR.getCode().toString(),GoodsException.GOODS_IS_CLEAR.getMessage());
        }

        //=====4.更新库存 包括 更新临时库存表（插入记录）以及更新reids数据
        //添加数据库临时库存表信息
        String stockId = saveQgGoodsTempStock(userID, goodsVo);

        goodsVo.setCurrentStock(goodsVo.getCurrentStock() - 1);//当前库存减一
        //更新redis商品库存信息
        redisUtil.setStr(Constants.goodsPrefix + goodsID, JSONObject.toJSONString(goodsVo));
        //缓存抢购用户标识
        redisUtil.setStr(Constants.QGUser.QGUserPrefix + goodsID + ":" + userID, Constants.QGUser.QGUserSucceed);

        //======5.生成订单
        saveOrder(stockId, goodsVo.getId(), userID, goodsVo.getPrice());
        //=======6.返回执行结果
        //删除锁
        redisUtil.del(Constants.Lock.lockPrefix + goodsID);
        //return DtoUtil.returnSuccess();


    }


    /*生成订单方法*/
    private void saveOrder(String stockId, String goodsId, String userId, double amount) throws Exception {
        QgOrder qgOrder = new QgOrder();
        qgOrder.setId(IdWorker.getId());
        qgOrder.setCreatedTime(new Date());
        qgOrder.setGoodsId(goodsId);
        qgOrder.setStatus(Constants.OrderStatus.toPay);
        qgOrder.setUpdatedTime(new Date());
        qgOrder.setUserId(userId);
        qgOrder.setAmount(amount);
        qgOrder.setNum(1);
        qgOrder.setOrderNo(IdWorker.getId());
        qgOrder.setStockId(stockId);
        qgOrderService.qdtxAddQgOrder(qgOrder);
    }

    /*
        保存抢购记录到库存临时表
         */
    public String saveQgGoodsTempStock(String userID, GoodsVo goodsVo) throws Exception {
        QgGoodsTempStock qgGoodsTempStock = new QgGoodsTempStock();
        qgGoodsTempStock.setId(IdWorker.getId());
        qgGoodsTempStock.setUserId(userID);
        qgGoodsTempStock.setCreatedTime(new Date());
        qgGoodsTempStock.setGoodsId(goodsVo.getId());
        qgGoodsTempStock.setStatus(Constants.StockStatus.lock);
        qgGoodsTempStock.setUpdatedTime(new Date());
        //保存临时库存数据
        qgGoodsTempStockService.qdtxAddQgGoodsTempStock(qgGoodsTempStock);
        return qgGoodsTempStock.getId();

    }

    /**
     * 发送抢购消息到消息中间件
     *
     * @param userID
     * @param goodsID
     * @return
     * @throws Exception
     */
    @Override
    public Dto sendQGMassage(String userID, String goodsID) throws Exception {
        //1========将消息封装成对象
        GetQGMassage getQGMassage = new GetQGMassage();
        getQGMassage.setUserID(userID);
        getQGMassage.setGoodsID(goodsID);
        actieMQaUtil.sendQueueMesage(Constants.ActiveMQMassage.Distnection, getQGMassage);
        return DtoUtil.returnSuccess();
    }


    /**
     * 前端轮询检查状态
     *
     * @param token
     * @param goodsID
     * @return
     * @throws Exception
     */
    @Override
    public Dto flushMassage(String token, String goodsID) throws Exception {

        //1=====获取用户信息
        String userJson = redisUtil.getStr(token);
        QgUser qgUser = JSONObject.parseObject(userJson, QgUser.class);
        //2=====通过用户状态判断信息
        String status = redisUtil.getStr(Constants.QGUser.QGUserPrefix + goodsID + ":" + qgUser.getId());
        if (EmptyUtils.isEmpty(status)) {
            return DtoUtil.returnFail(GoodsException.GOODS_IS_GETTING.getMessage(), GoodsException.GOODS_IS_GETTING.getCode().toString());
        } else if (status.equals("0")) {
            return DtoUtil.returnFail(GoodsException.GOODS_IS_CLEAR.getMessage(), GoodsException.GOODS_IS_CLEAR.getCode().toString());
        } else if (status.equals("2")) {
            return DtoUtil.returnFail(GoodsException.USER_REPEAT_GET.getMessage(), GoodsException.USER_REPEAT_GET.getCode().toString());
        }else{
            return DtoUtil.returnSuccess();
        }

    }
}


